package com.ean.backpack.validator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import com.ean.backpack.dto.SearchFormDTO;
import com.ean.backpack.dto.SearchRoom;

@Component
public class SearchFormValidator implements Validator {

	@Override
	public boolean supports(Class<?> clazz) {
		return SearchFormDTO.class.equals(clazz);
	}

	@Override
	public void validate(Object target, Errors errors) {
		SearchFormDTO search = (SearchFormDTO) target;
		Pattern rejected = Pattern
				.compile("[\\[\\]{}<>`~!@#$%^*_=+?/|\\\\;:\"]"), date = Pattern
				.compile("^(\\d{1,2})(\\/|-)(\\d{1,2})(\\/|-)(\\d{4})$");
		Matcher matcher;

		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "destination",
				"destination.required");
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "startDate",
				"startDate.required");
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "endDate",
				"endDate.required");

		if (search.getDestination() != null) {
			matcher = rejected.matcher(search.getDestination());
			if (search.getDestination().length() > 85) {
				errors.rejectValue("destination", "destination.overlimit");
			}

			if (matcher.find()) {
				errors.rejectValue("destination", "destination.invalid");
			}
		}

		/* Data validation */
		if (search.getStartDate() != null) {
			matcher = date.matcher(search.getStartDate());

			if (!matcher.find()) {
				errors.rejectValue("startDate", "startDate.format");
			}
		}

		if (search.getEndDate() != null) {
			matcher = date.matcher(search.getEndDate());
			if (!matcher.find()) {
				errors.rejectValue("endDate", "endDate.format");
			}
		}

		/* ROOM VALIDATION */
		int i = 0;
		if (search.getRooms().size() > 0) {
			for (SearchRoom room : search.getRooms()) {
				if (room != null) {
					if (room.getAdultsCount() != null) {
						if (room.getAdultsCount() == 0) {
							errors.rejectValue("rooms[" + i + "].adultsCount",
									"adultsCount.required");
						} else if (room.getAdultsCount() > 4) {
							errors.rejectValue("rooms[" + i + "].adultsCount",
									"adultsCount.notAllowed.upper");
						} else if (room.getAdultsCount() < 0) {
							errors.rejectValue("rooms[" + i + "].adultsCount",
									"adultsCount.notAllowed.lower");
						}
					} else {
						errors.rejectValue("rooms[" + i + "].adultsCount",
								"adultsCount.required");
					}
					if (room.getChildrenCount() != null) {
						if (room.getChildrenCount() < 0) {
							errors.rejectValue(
									"rooms[" + i + "].childrenCount",
									"childrenCount.notAllowed.lower");
						} else if (room.getChildrenCount() > 4) {
							errors.rejectValue(
									"rooms[" + i + "].childrenCount",
									"childrenCount.notAllowed.upper");
						} else {
							for (Integer age : room.getChildAges()) {
								if (age != null) {
									if (age < 0) {
										errors.rejectValue("rooms[" + i
												+ "].childAges",
												"childAge.notAllowed.lower");
										break;
									} else if (age > 18) {
										errors.rejectValue("rooms[" + i
												+ "].childAges",
												"childAge.notAllowed.upper");
										break;
									}
								} else {
									errors.rejectValue("rooms[" + i
											+ "].childAges",
											"childAge.required");
								}
							}
						} // End else
					}
					i++;
				}
			}
		} // End room validation

	} // End validate method

} // End class
